package com.dage.salesflow.excel;

import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.util.BooleanUtils;
import com.alibaba.excel.util.MapUtils;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Map;

/**
 * Excel导出写入拦截器
 * 可配置表头备注、样式
 */
public class ExcelWriteHandler implements RowWriteHandler, CellWriteHandler {

	private Map<String, HeadNotation> notations;
	private Map<String, HeadStyle> styles;
	private final boolean headStyle;

	public ExcelWriteHandler(Class<?> clazz) {
		this(clazz, false);
	}

	/**
	 * 初始化
	 *
	 * @param clazz     Excel模型类
	 * @param headStyle 是否应用表头样式
	 */
	public ExcelWriteHandler(Class<?> clazz, boolean headStyle) {
		this.headStyle = headStyle;
		if (headStyle) {
			notations = getAnnotationMap(clazz, HeadNotation.class);
			styles = getAnnotationMap(clazz, HeadStyle.class);
		}
	}

	/**
	 * 获取自定义注解
	 */
	private <T> Map<String, T> getAnnotationMap(Class<?> clazz, Class<? extends Annotation> notation) {
		Map<String, T> annotationMap = MapUtils.newHashMap();
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			if (!field.isAnnotationPresent(notation) || !field.isAnnotationPresent(ExcelProperty.class)) {
				continue;
			}
			Annotation annotation = field.getAnnotation(notation);
			ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
			annotationMap.put(String.join("", excelProperty.value()), (T) annotation);
		}
		return annotationMap;
	}

	@Override
	public void afterCellDispose(CellWriteHandlerContext context) {
		if (headStyle && BooleanUtils.isTrue(context.getHead())) {
			WriteCellData<?> cellData = context.getFirstCellData();
			String value = cellData.getStringValue();
			if (styles.containsKey(value)) {
				WriteCellStyle style = cellData.getOrCreateStyle();
				style.setFillBackgroundColor(styles.get(value).value());
				style.setFillForegroundColor(styles.get(value).fillColor());
				//				WriteFont font = new WriteFont();
				//				font.setColor(IndexedColors.RED.index);
				//				font.setBold(true);
				//				font.setFontHeightInPoints(style.getWriteFont().getFontHeightInPoints());
				//				font.setFontName("微软雅黑");
				//				style.setWriteFont(font);
				cellData.setWriteCellStyle(style);
			}
		}
	}

	@Override
	public void afterRowDispose(RowWriteHandlerContext context) {
		if (headStyle && BooleanUtils.isTrue(context.getHead())) {
			Sheet sheet = context.getWriteSheetHolder().getSheet();
			Drawing<?> drawingPatriarch = sheet.createDrawingPatriarch();
			//设置备注
			Row row = context.getRow();
			for (int i = 0; i < row.getPhysicalNumberOfCells(); i++) {
				Cell cell = row.getCell(i);
				if (notations.containsKey(cell.getStringCellValue())) {
					HeadNotation notation = notations.get(cell.getStringCellValue());
					// 创建一个批注
					Comment comment =
							drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), 0, (short) notation.cols(), notation.rows()));
					// 输入批注信息
					comment.setString(new XSSFRichTextString(notation.value()));
					cell.setCellComment(comment);
				}
			}
		}
	}
}
